subroutine readsrce(lunit,t_array0,myrank)
  use param
  use data_param,only:grfn
  use data_param,only:geom_exist
  use data_param,only:source_exist
  use data_param,only:n_source_data
  use data_param,only:n_geom_data
  use geom_data_param,only:n_geom_obj
  use geom_data_param,only:geom_obj
  implicit none

  interface
     integer function str2label(str)
       character :: str*(*)
     end function str2label
  end interface

  integer,intent(in) :: lunit,t_array0(8),myrank

  integer :: nunit,count_line,len_str,asci_code
  character(len=len_linebuf) :: eatline,str
  character(len=len_wordbuf),dimension(max_n_word) :: eatword
  character(len=8) :: d_time_str

  integer :: i,j
  integer :: gid,lid,ndiss,nd
  integer :: in1,in2,pos1,pos2,w,w2

  if (.not.source_exist) return
  if (.not.geom_exist) return
  if (n_geom_obj.eq.0) return

  in1=1
  in2=2
  w=78
  w2=28

  call log_msg1(lunit,"")
  call log_msg1(lunit,"Message from the subourinte (readsrce)")

  call log_msg1(lunit,"")
  write(lunit,'(1x,"List of sources from the geometric objects")')
  
  call drawline(lunit,in1,w)
  write(lunit,'(1x,"gid",1x,&
                4x,"gtype",4x,&
                1x,"ndiss",1x,&
                2x,"n",2x,&
                5x,"diss_type")')
  call drawline(lunit,in1,w)

  nunit=1

  open(unit=nunit,file=grfn,status='old',err=103)

  count_line=0
  do
     read(nunit,'(a)',end=100,err=101) eatline
     count_line=count_line+1
     len_str=len_trim(eatline)
     if (len_str.eq.0) cycle
     eatline=adjustl(eatline)
     asci_code=ichar(eatline(1:1))
     if (asci_code.eq.ccode) cycle
     read(eatline(1:len_str),*,end=102) &
          (eatword(i),i=1,max_n_word)
102  continue

     ! read the index of geometric object
     read(eatword(1),*) gid
     if (gid.lt.1.or.gid.gt.n_geom_obj) then
        call terminal_msg1(trim(adjustl(eatline)))
        call abnormal_stop("readsrce",&
             "The index of geometric object is out of range.")
     end if

     pos1=0

     pos2=pos1+5
     write(str(pos1+1:pos2),'("[",i3.3,"]")') gid
     pos1=pos2

     select case(geom_obj(gid)%geom_type)
     case(1)
        ! point
        ! width=9(+4x)
        pos2=pos1+13
        write(str(pos1+1:pos2),'(4x,"point (1)")')
        pos1=pos2

     case(2)
        ! staight line
        ! width=8(+5x)
        pos2=pos1+13
        write(str(pos1+1:pos2),'(5x,"line (2)")')
        pos1=pos2

     case(3)
        ! x=a,left
        ! width=10(+3x)
        pos2=pos1+13
        write(str(pos1+1:pos2),'(3x,"x-left (3)")')
        pos1=pos2

     case(4)
        ! x=a,right
        ! width=11(+2x)
        pos2=pos1+13
        write(str(pos1+1:pos2),'(2x,"x-right (4)")')
        pos1=pos2

     case(5)
        ! y=b,left
        ! width=10(+3x)
        pos2=pos1+13
        write(str(pos1+1:pos2),'(3x,"y-left (5)")')
        pos1=pos2

     case(6)
        ! y=b,right
        ! width=11(+2x)
        pos2=pos1+13
        write(str(pos1+1:pos2),'(2x,"y-right (6)")')
        pos1=pos2

     case(7)
        ! z=c,left
        ! width=10
        pos2=pos1+13
        write(str(pos1+1:pos2),'(3x,"z-left (7)")')
        pos1=pos2

     case(8)
        ! z=c,right
        ! width=11(+2x)
        pos2=pos1+13
        write(str(pos1+1:pos2),'(2x,"z-right (8)")')
        pos1=pos2

     case default
     end select

     n_source_data=n_source_data+1

     ! number of ways for dissociation
     read(eatword(2),*) ndiss

     pos2=pos1+7
     write(str(pos1+1:pos2),'(2x,i3.3,2x)') &
          ndiss
     pos1=pos2

     if (ndiss.eq.0) cycle
     if (ndiss.gt.0) continue

     geom_obj(gid)%does_diss=.true.
     geom_obj(gid)%diss_type=ndiss

     ! allocate memories
     allocate(geom_obj(gid)%diss_eb(ndiss))
     allocate(geom_obj(gid)%diss_nu(ndiss))
     allocate(geom_obj(gid)%diss_rd(ndiss))
     allocate(geom_obj(gid)%diss_const_rate(ndiss))
     allocate(geom_obj(gid)%diss_n(ndiss))
     allocate(geom_obj(gid)%diss_obj(ndiss))

     ! read the first line
     read(eatword(3),*) geom_obj(gid)%diss_eb(1)
     read(eatword(4),*) geom_obj(gid)%diss_nu(1)
     read(eatword(5),*) geom_obj(gid)%diss_rd(1)
     read(eatword(6),*) nd
     geom_obj(gid)%diss_n(1)=nd
     allocate(geom_obj(gid)%diss_obj(1)%diss_type(nd))

     pos2=pos1+5
     write(str(pos1+1:pos2),'(2x,i1,2x)') nd
     pos1=pos2

     ! read associated objects
     do i=1,nd
        lid=str2label(eatword(6+i))
        if (lid.eq.0) then
           call terminal_msg1(trim(adjustl(eatline)))
           call abnormal_stop("readsrce",&
                "Error occurs in the set of diss for geom obj.")
        end if
        geom_obj(gid)%diss_obj(1)%diss_type(i)=lid

        pos2=pos1+12
        write(str(pos1+1:pos2),'(1x,a10,1x)') trim(eatword(6+i))
        pos1=pos2
     end do

     call log_msg1_indent(lunit,in1,str(1:pos2))

     ! additional types of dissociation
     do i=2,ndiss
        read(nunit,'(a)',err=101) eatline
        count_line=count_line+1
        len_str=len_trim(eatline)
        if (len_str.eq.0) cycle
        eatline=adjustl(eatline)
        asci_code=ichar(eatline(1:1))
        if (asci_code.eq.ccode) cycle
        read(eatline(1:len_str),*,end=104) &
             (eatword(j),j=1,max_n_word)
104     continue

        read(eatword(1),*) geom_obj(gid)%diss_eb(i)
        read(eatword(2),*) geom_obj(gid)%diss_nu(i)
        read(eatword(3),*) geom_obj(gid)%diss_rd(i)
        read(eatword(4),*) nd
        geom_obj(gid)%diss_n(i)=nd
        allocate(geom_obj(gid)%diss_obj(i)%diss_type(nd))

        pos1=0

        pos2=pos1+3
        write(str(pos1+1:pos2),'(i1,2x)') nd
        pos1=pos2

        do j=1,nd
           lid=str2label(eatword(4+j))
           if (lid.eq.0) then
              call terminal_msg1(trim(adjustl(eatline)))
              call abnormal_stop("readsrce",&
                   "Error occurs in the set of diss for geom obj.")
           end if
           geom_obj(gid)%diss_obj(i)%diss_type(j)=lid

           pos2=pos1+12
           write(str(pos1+1:pos2),'(1x,a10,1x)') trim(eatword(4+j))
           pos1=pos2
        end do

        call log_msg1_indent(lunit,w2,str(1:pos2))
     end do

  end do

103 continue
  call abnormal_stop("readsrce",&
       "Error occurs while the diss for geom file opens.")

101 continue
  call abnormal_stop("readgeom",&
       "Error occurs during reading the diss for geom file.")
  
100 continue

  close(nunit)

  call drawline(lunit,in1,w)

  call print_d_time(t_array0,d_time_str)
  if (myrank.eq.0) &
       write(*,'(a8,":READSRCE DONE.")') d_time_str(1:8)
  write(lunit,*)
  write(lunit,'(a8,":READSRCE DONE.")') d_time_str(1:8)

  return

end subroutine readsrce
